package com.yds.coroutine

import android.os.Bundle
import android.util.Log
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatButton
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine

class CoroutineActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContentView(R.layout.activity_coroutine)

        findViewById<AppCompatButton>(R.id.串行请求).setOnClickListener {
            串行请求()
        }

        findViewById<AppCompatButton>(R.id.并行请求).setOnClickListener {
            并行请求()
        }

        findViewById<AppCompatButton>(R.id.串行与并行结合请求).setOnClickListener {
            串行与并行结合请求()
        }

        findViewById<AppCompatButton>(R.id.挂起函数).setOnClickListener {
            挂起函数()
        }
    }

    private fun 挂起函数() {
        CoroutineScope(Dispatchers.Default).launch {
            try {
                val result = requestHttpSuspend("A")
                val result1 = requestHttpSuspend(result)
                val result2 = requestHttpSuspend(result1)
                Log.i("YDSimon", "挂起函数 = $result2")
            } catch (e: java.lang.Exception) {
                Log.i("YDSimon", "挂起函数Exception = ${e.message}")
            }
        }
    }

    private suspend fun requestHttpSuspend(url: String): String {
        return suspendCoroutine {
            val request = HttpRequest(url)
            request.getMethod(object : HttpRequest.CallBack {
                override fun doSuccess(result: String) {
                    it.resume("success")
                }

                override fun doFailed() {
                    it.resumeWithException(Exception("failed"))
                }
            })
        }
    }

    class HttpRequest(url: String) {
        var requestCount = 0

        interface CallBack {
            fun doSuccess(result: String)
            fun doFailed()
        }

        fun getMethod(callback: CallBack) {
            Thread.sleep(1000)
            requestCount++
            if (requestCount == 2) {
                callback.doFailed()
                return
            }
            callback.doSuccess("success")
        }
    }

    private fun 串行请求() {
        CoroutineScope(Dispatchers.Default).launch {
            withContext(Dispatchers.Default) {
                doA()
            }
            withContext(Dispatchers.Default) {
                doB()
            }
            withContext(Dispatchers.Default) {
                doC()
            }
        }
    }

    private fun 并行请求() {
        CoroutineScope(Dispatchers.Default).launch {
            val deferred1=  async {
                doA()
            }
            val deferred2=  async {
                doB()
            }
            val deferred3=  async {
                doC()
            }

            deferred1.await()
            deferred2.await()
            deferred3.await()
        }
    }

    private fun 串行与并行结合请求() {
        CoroutineScope(Dispatchers.Default).launch {
            withContext(Dispatchers.Default) {
                doA()
            }
            val deferred2=  async {
                doB()
            }
            val deferred3=  async {
                doC()
            }

            deferred2.await()
            deferred3.await()
        }
    }

    private suspend fun doA() {
        delay(3000)
        Log.i("YDSimon", "doA-3000")
    }

    private suspend fun doB() {
        delay(5000)
        Log.i("YDSimon", "doB-5000")
    }

    private suspend fun doC() {
        delay(4000)
        Log.i("YDSimon", "doC-4000")
    }
}